#ifndef numuCC1P1PiSelection_h
#define numuCC1P1PiSelection_h

#include "SelectionBase.hxx"
#include "Parameters.hxx"

//TODO: has to be changed later t nd280Samples::kFGD1NuMuCC1P1Pi
const nd280Samples::SampleEnum gkSampleEnumCC1P1Pi = nd280Samples::kFGD1NuMuCCQE;

class numuCC1P1PiSelection: public SelectionBase{
public:
    numuCC1P1PiSelection(bool forceBreak=true);
    virtual ~numuCC1P1PiSelection(){}
    
    //---- These are mandatory functions
    void DefineSteps();
    inline AnaBoxB* MakeBox();
    bool FillEventSummary(const AnaBoxB& box, AnaEventB& event, Int_t allCutsPassed[]);
    
    nd280Samples::SampleEnum GetSampleEnum(){return gkSampleEnumCC1P1Pi;}
};

class AnaBoxCC1P1Pi: public AnaBoxB{
    
public:
    
    AnaBoxCC1P1Pi() {
        MuonCandidate = ProtonCandidate = PionCandidate = NULL;
    }
    virtual ~AnaBoxCC1P1Pi(){}
    
    std::vector<AnaTrackB*> TrackerTracks;
    
    /// For storing tracks with TPC information in the bunch.
    std::vector<AnaTrackB*> TPCtracks;
    std::vector<AnaTrackB*> NegativeTPCtracksOutFV;
    std::vector<AnaTrackB*> PositiveTPCtracksOutFV;
    std::vector<AnaTrackB*> BadQuaTPCtracksInFV;
    std::vector<AnaTrackB*> BadQuaTPCtracksOutFV;
    
    /// For storing tracks with FGD information in the bunch.
    std::vector<AnaTrackB*> FGDtracks;
    std::vector<AnaTrackB*> FGDtracksCrossingFGD1;
    std::vector<AnaTrackB*> FGDtracksInFGD1Volume;
    std::vector<AnaTrackB*> FGDContTracksInFV;
    std::vector<AnaTrackB*> FGDNotContTracksInFV;
    std::vector<AnaTrackB*> FGDContTracksOutFV;
    std::vector<AnaTrackB*> FGDNotContTracksOutFV;
    
    // neut counters
    int Nmuons;
    int Nprotons;
    int Npions;
    
    AnaTrackB* MuonCandidate;
    AnaTrackB* ProtonCandidate;
    AnaTrackB* PionCandidate;
};

inline AnaBoxB* numuCC1P1PiSelection::MakeBox() {return new AnaBoxCC1P1Pi();}

namespace std_numucc1P1Pi_actions{
    void FindTracksWithTPC(const AnaEventB& event, AnaBoxCC1P1Pi& box, bool qualityCut = true, SubDetId::SubDetEnum det = SubDetId::kFGD1);
    void FindTracksWithFGDAndNoTPC(const AnaEventB& event, AnaBoxCC1P1Pi& box, SubDetId::SubDetEnum det = SubDetId::kFGD1);
    /// Find the correct sense of a secondary track by comparing its start and end positions with the vertex
    //void FindCorrectSense(AnaTrackB* track, AnaVertexB* vertex);
}
namespace std_numucc1P1Pi_cuts{
    Bool_t IsProton(AnaTrackB * track);
    Bool_t IsPion(AnaTrackB * track);
}

class FindMichelElectronsAction: public StepBase{
public:
    using StepBase::Apply;
    bool Apply(const AnaEventB& event, AnaBoxB& box) const;
    StepBase* MakeClone(){return new FindMichelElectronsAction();}
};

class MichelElectronCut: public StepBase{
public:
    using StepBase::Apply;
    bool Apply(const AnaEventB& event, AnaBoxB& box) const;
    StepBase* MakeClone(){return new MichelElectronCut();}
};

class FindTrackerTracksAction: public StepBase{
public:
    using StepBase::Apply;
    bool Apply(const AnaEventB& event, AnaBoxB& box) const;
    StepBase* MakeClone(){return new FindTrackerTracksAction();}
};

class TrackChargeCut: public StepBase{
public:
    using StepBase::Apply;
    bool Apply(const AnaEventB& event, AnaBoxB& box) const;
    StepBase* MakeClone(){return new TrackChargeCut();}
};

class ParticlePIDCut: public StepBase{
public:
    using StepBase::Apply;
    bool Apply(const AnaEventB& event, AnaBoxB& box) const;
    StepBase* MakeClone(){return new ParticlePIDCut();}
};

class CommonVertexCut: public StepBase{
public:
    CommonVertexCut(){
        _cutX = ND::params().GetParameterI("psycheSelections.numuCCQE.CutX1");
        _cutY = ND::params().GetParameterI("psycheSelections.numuCCQE.CutY1");
        _cutZ = ND::params().GetParameterI("psycheSelections.numuCCQE.CutZ1");
    }
    using StepBase::Apply;
    bool Apply(const AnaEventB& event, AnaBoxB& box) const;
    StepBase* MakeClone(){return new CommonVertexCut();}
private:
    int _cutX;
    int _cutY;
    int _cutZ;
};

/*class FindCorrectParticleSenseAction: public StepBase{
public:
    using StepBase::Apply;
    bool Apply(const AnaEventB& event, AnaBoxB& box) const;
    StepBase* MakeClone(){return new FindCorrectParticleSenseAction();}
};*/

#endif
